﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace project1
{
    public partial class Form1 : Form
    {
        private static int NUM_CLUSTERS = 2;//
        private static int TOTAL_DATA = 5;//
        private static List<Data> SAMPLES = new List<Data>();
        private static List<Data> dataset = new List<Data>();
        private static List<Centroid> centroids = new List<Centroid>();
        public Form1()
        {
            InitializeComponent();
        }

        private void initialize()
        {
            rtb_thongbao.Text = "Centroids initialized at:\n";

            List<double> lst = new List<double>();
            lst.Add(1.0);
            lst.Add(2.0);
            lst.Add(3.0);
            Centroid c = new Centroid(lst);
            centroids.Add(c);

            lst = new List<double>();
            lst.Add(10.0);
            lst.Add(2.0);
            lst.Add(3.0);
            c = new Centroid(lst);
            centroids.Add(c);

            for (int i = 0; i < NUM_CLUSTERS; i++)
            {
                String Out="( ";
                for (int j = 0; j < centroids[i].getDimension(); j++)
                {
                    Out = Out + centroids[i].getElementAt(j).ToString();
                    if (j < centroids[i].getDimension()-1)
                        Out +=",";
                }
                rtb_thongbao.Text += Out + " )\n";
                
            }
            return;
        }

        private static void kMeanCluster()
        {
            double bigNumber = Math.Pow(10, 10);
            double minimum = bigNumber;
            double distance = 0.0;
            int sampleNumber = 0;
            int cluster = 0;
            bool isStillMoving = true;
            Data newData = null;
            while (dataset.Count < TOTAL_DATA)
            {
                List<double> lstnewData = new List<double>();
               // lstnewData.Add(SAMPLES[sampleNumber].getElementAt(0));//
               // lstnewData.Add(SAMPLES[sampleNumber].getElementAt(1));
                for (int sp = 0; sp < SAMPLES[sampleNumber].getDimension(); sp++)
                {
                    lstnewData.Add(SAMPLES[sampleNumber].getElementAt(sp));
                }
                newData = new Data(lstnewData);
                dataset.Add(newData);
                minimum = bigNumber;

                for (int i = 0; i < NUM_CLUSTERS; i++)
                {
                    distance = dist(newData, centroids[i]);
                    if (distance < minimum)
                    {
                        minimum = distance;
                        cluster = i;
                    }
                }
                newData.cluster(cluster);
                for (int i = 0; i < NUM_CLUSTERS; i++) // duyet toan bo cac cluster
                {
                    double[] totalOfDimensons = new double[newData.getDimension()];
                    int totalInCluster = 0;
                    for (int j = 0; j < dataset.Count; j++)
                    {
                        if (dataset[j].cluster() == i)
                        {
                            //totalOfDimensons[0] += dataset[j].getElementAt(0);//
                           // totalOfDimensons[1] += dataset[j].getElementAt(1);
                           // totalInCluster++;
                            //
                            for (int sp2 = 0; sp2 < centroids[i].getDimension(); sp2++)
                            {
                                totalOfDimensons[sp2] += dataset[j].getElementAt(sp2);
                            }
                            totalInCluster++;
                        }

                    }
                    if (totalInCluster > 0)
                    {
                        //centroids[i].setElementAt(0, totalOfDimensons[0] / totalInCluster);//
                        //centroids[i].setElementAt(1, totalOfDimensons[1] / totalInCluster);
                        for (int sp2 = 0; sp2 < centroids[i].getDimension(); sp2++)
                        {
                            centroids[i].setElementAt(sp2, totalOfDimensons[sp2] / totalInCluster);
                        }
                    }

                }
                sampleNumber++;
            }
            while (isStillMoving)
            {
                for (int i = 0; i < NUM_CLUSTERS; i++)
                {
                    double[] totalOfDimensons = new double[newData.getDimension()];
                    int totalInCluster = 0;
                    for (int j = 0; j < dataset.Count; j++)
                    {
                        if (dataset[j].cluster() == i)
                        {
                            for (int sp2 = 0; sp2 < centroids[i].getDimension(); sp2++)
                            {
                                totalOfDimensons[sp2] += dataset[j].getElementAt(sp2);
                            }
                            totalInCluster++;
                        }

                    }
                    if (totalInCluster > 0)
                    {
                        for (int sp2 = 0; sp2 < centroids[i].getDimension(); sp2++)
                        {
                            centroids[i].setElementAt(sp2, totalOfDimensons[sp2] / totalInCluster);
                        }
                    }
                }
                isStillMoving = false;
                for (int i = 0; i < dataset.Count; i++)
                {
                    Data tempData = dataset[i];
                    minimum = bigNumber;
                    for (int j = 0; j < NUM_CLUSTERS; j++)
                    {
                        distance = dist(tempData, centroids[j]);
                        if (distance < minimum)
                        {
                            minimum = distance;
                            cluster = j;
                        }
                    }
                    tempData.cluster(cluster);
                    if (tempData.cluster() != cluster)
                    {
                        tempData.cluster(cluster);
                        isStillMoving = true;
                    }
                }
            }
            return;

        }

        private List<double> toDoubleArray(String[] p1)
        {
            List<double> lst = new List<double>();
            for (int i = 0; i < p1.Length; i++)
            {
                double x = Double.Parse(p1[i]);
                lst.Add(x);
            }
            return lst;
        }

        private void createListData()
        {
            List<double> lst = new List<double>();
            lst.Add(1.0);
            lst.Add(2.0);
            lst.Add(3.0);
            Data d = new Data(lst);
            SAMPLES.Add(d);

            lst = new List<double>();
            lst.Add(3.0);
            lst.Add(4.0);
            lst.Add(5.0);
            d = new Data(lst);
            SAMPLES.Add(d);

            lst = new List<double>();
            lst.Add(3.0);
            lst.Add(4.0);
            lst.Add(5.0);
            d = new Data(lst);
            SAMPLES.Add(d);

            lst = new List<double>();
            lst.Add(7.0);
            lst.Add(8.0);
            lst.Add(9.0);
            d = new Data(lst);
            SAMPLES.Add(d);

            lst = new List<double>();
            lst.Add(10.0);
            lst.Add(2.0);
            lst.Add(3.0);
            d = new Data(lst);
            SAMPLES.Add(d);
            /*
            lst = new List<double>();
            lst.Add(3.5);
            lst.Add(5.0);
            d = new Data(lst);
            SAMPLES.Add(d);

            lst = new List<double>();
            lst.Add(4.5);
            lst.Add(5.0);
            d = new Data(lst);
            SAMPLES.Add(d);

            lst = new List<double>();
            lst.Add(3.5);
            lst.Add(4.5);
            d = new Data(lst);
            SAMPLES.Add(d);
             * */
        }

        private static double dist(Data d, Centroid c)
        {
            double sum = 0.0;
            for (int i = 0; i < d.getDimension(); i++)
            {
                double x = d.getElementAt(i) - c.getElementAt(i);
                sum += (x * x);
            }
            return Math.Sqrt(sum);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            List<double> lst=this.toDoubleArray(new String[] { "1", "2", "3", "4" });
           // createListData();
           // initialize();
            
            
           // kMeanCluster();
           
           // for (int i = 0; i < NUM_CLUSTERS; i++)
           // {
           //     rtb_thongbao.Text += "Cluster " + i.ToString() + " includes:\n";
           //     for (int j = 0; j < TOTAL_DATA; j++)
           //     {
           //         if (dataset[j].cluster() == i)
           //         {
           //             rtb_thongbao.Text += "     (" + dataset[j].getElementAt(0) + ", " + dataset[j].getElementAt(1) + "," + dataset[j].getElementAt(2) + ")\n";
           //         }
           //     }
           //     rtb_thongbao.Text += "\n";
           // }
            
           //rtb_thongbao.Text += "Centroids finalized at:\n";
           //for (int i = 0; i < NUM_CLUSTERS; i++)
           //{
           //    rtb_thongbao.Text += "     (" + centroids[i].getElementAt(0) + ", " + centroids[i].getElementAt(1)+")\n";
           //}
           //rtb_thongbao.Text += "\nEND";
            
        }
    }
}
